var timerId =null ;
var timers = new Array();


function animate(elem, params,times, cb){
	var opt =getOpt(params,times,cb);
	var self = elem;
	for(var p in params){
		if(p=='deep_clone' || p=='toJSON')continue;
		var e = new fx(self,opt,params,p);
		e.custom();
	}
}

function getOpt(params,times,cb){
	
	var opt = {};
	opt.curAnim = {};
	for(var p in params){
		
		if(p=='deep_clone' || p=='toJSON')continue;
		
		opt.curAnim[p]=false;
	}
	opt.times = 3; 
	if(times){
		opt.times = times;
	}
	opt.callback = cb;
	return opt;
	
}

var fx = function(self,opt,params,name){
	this.options = {};
	for(var i in opt){
		if(i=='deep_clone' || i=='toJSON')continue;
		this.options[i] = opt[i];
	}
	
	
	this.start = self.style[name];
	this.end = params[name];
	this.addValue = (this.end - this.start)/this.options.times;
	this.step = -2;
	this.self = self;
	this.name = name;
	
}

fx.prototype = {
	move:function(gotoEnd){
		this.step++;
		
		if(this.step<=0){
			return true;
		}
		
		if(gotoEnd || this.options.times <= this.step){
			this.self.style[this.name] = this.end+'px';
			this.options.curAnim[this.name] = true;
			
			var done = true;
			for (var i in this.options.curAnim) {
				if(i=='deep_clone' || i=='toJSON')continue;
				if (this.options.curAnim[i] !== true) 
					done = false;
			}
			if(done){
				if(this.options.callback)
					this.options.callback.call( this.self );
			}
			return false;
		}else{
			
			var cur = parseInt(this.self.style[this.name]);
			cur += this.addValue;
			this.self.style[this.name] = cur+'px'; 
			
			
			return true;
		}
	},
	custom:function(){
		var self = this;

		function t(gotoEnd){	

			return self.move(gotoEnd);
		}
		t.elem = this.self;
		t.elemName = this.name;
		t.callback = this.options.callback;
		
		if (t() && timers.push(t) == 1) {
			
			timerId = setInterval(function(){
				
				for ( var i = 0; i < timers.length; i++ ){
					if ( !timers[i]() )
						timers.splice(i--, 1);
						
					
					if ( timers.length < 1 ) {
						clearInterval( timerId );
						timerId = null;
					}
				}
			}, 20);
			
		}
	},
}

function stopAnimate(elem ,gotoEnd,doCallBack){
	if(timers && timers.length > 0){
		
		for ( var i = 0; i < timers.length; i++ ){
			
			if(timers[i].elem == elem || timers[i].elem.id == elem.id){
				if(gotoEnd){
					timers[i](gotoEnd) ;
				}else{
					if(timers[i].callback){
						
						if(typeof(doCallBack)=='boolean' ){
							if(doCallBack){
								timers[i].callback.call( timers[i].elem );
							}
						}
						
					}
				}
				
				timers.splice(i--, 1);
				
			}
		}
		if (timers.length < 1) {
			clearInterval(timerId);
			timerId = null;
		}
	}
}